use 5.26.0;
use strict;
use warnings;
use experimentals;
use File::Spec;
use Win32::Process;
use Win32;
use Data::Dumper qw( Dumper );
use File::Copy;
use threads;
use Thread::Queue;

my @stdf_folder_list = map { File::Spec->rel2abs( $_ ) } grep { -e -d $_ } @ARGV;
my $perl_file_path = $ENV{ STDF_PARSER_SCRIPT_PATH };

if( not ( defined $perl_file_path and -e $perl_file_path ) ){
    die "Fail to get STDF_Parser script file path by SYTEM ENV 'STDF_PARSER_SCRIPT_PATH', or given path is not existed";
}

# my $perl_file_path = 'C:\Users\yunlong_cui\Documents\work_related\04_script\01_STDF_Parser\parse_stdf.pl';
my $q = Thread::Queue->new();
$| = 1;

sub ErrorReport{
    print Win32::FormatMessage( Win32::GetLastError() );
}

sub get_child_folder( $root_folder, $folder_name ){
    my $sub_folder_name = File::Spec->catdir( $root_folder, $folder_name );
    if( not -e $sub_folder_name ){
        mkdir $sub_folder_name or die "Failled to create sub folder: $folder_name";
    }
    return $sub_folder_name;
}

sub stdf_parser_thd{
    my $core_index = shift @_;
    my $prc_mask = 2 ** ( $core_index - 1 );
    while (defined(my $stdf_file_path = $q->dequeue())) {
        ( my $output_csv_file_name = $stdf_file_path ) =~ s/\.std(?:f)*(?:\.gz)*$/_output.txt/ismx;
        say "start to process $stdf_file_path";
        # say `perl $perl_file_path "$stdf_file_path" "$output_csv_file_name" `;
        my $prc_obj;
        Win32::Process::Create(
            $prc_obj,
            'C:\Strawberry\perl\bin\perl.exe',
            qq{ "$perl_file_path" "$stdf_file_path" "$output_csv_file_name" },
            0,
            NORMAL_PRIORITY_CLASS,
            "."
        ) or die "Fail to create Process " .  ErrorReport();
        my ( $a, $b );
        $prc_obj->GetProcessAffinityMask( $a, $b );
        $prc_obj->SetProcessAffinityMask( $prc_mask );
        if( $prc_obj->Wait( 1*3600*1000 ) ){
            ( my $root_folder = $stdf_file_path ) =~ s/[\/\\][^\/\\]+$//ismxg;

            ( undef, undef, my $basename ) = File::Spec->splitpath( $stdf_file_path );
            move( $stdf_file_path, File::Spec->catfile( $root_folder, 'Processed', $basename ) );
        }else{
            $prc_obj->kill(22);
            say "Procssing $output_csv_file_name fail, timeout.";
        }

        say "Finished process.";
    }
}

my @threads_list = map { threads->create( \&stdf_parser_thd , $_ ) } 1..6;

foreach my $stdf_folder ( @stdf_folder_list ){
    opendir my $dir_h, $stdf_folder or die "Failed to open $stdf_folder: $!";
    get_child_folder( $stdf_folder, 'Processed' );
    while( my $stdf_file = readdir $dir_h ){
        next if not $stdf_file =~ /\.std(?:f)*(?:\.gz)*$/ismx;
        my $stdf_file_path = File::Spec->catfile( $stdf_folder, $stdf_file );
        $q->enqueue( $stdf_file_path );
    }
    close $dir_h;
}

$q->end;

foreach (@threads_list){
    $_->join;
}